package tps12.axwax.client.view;

import java.util.ArrayList;
import java.util.List;

import tps12.axwax.client.presenter.SolvePuzzlePresenter.GridDisplay;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class PuzzleGrid extends Composite implements GridDisplay {
	interface MyUiBinder extends UiBinder<Grid, PuzzleGrid> {}
	private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
	
	interface Style extends CssResource {
		// styles applied to cell panels
		String cell();
		String topBar();
		String leftBar();
		String bottomEdge();
		String rightEdge();
		
		String light();
		String selected();
		
		// styles applied to number labels
		String number();
		String leftBarNumber();
		String topBarNumber();
		
		// styles applied to letter entry
		String letter();
		String topBarLetter();
		String leftBarLetter();
	}
	
	@UiField Style style;
	
	@UiField(provided=true) Grid grid;
	
	List<List<Label>> spaces;
 
	public PuzzleGrid(Grid grid) {
		this.grid = grid;
		initWidget(uiBinder.createAndBindUi(this));
		
		spaces = new ArrayList<List<Label>>(grid.getRowCount());
		for (int i = 0; i < grid.getRowCount(); i++) {
			spaces.add(new ArrayList<Label>(grid.getCellCount(i)));
			for (int j = 0; j < grid.getCellCount(i); j++) {
				AbsolutePanel cell = new AbsolutePanel();
				cell.addStyleName(style.cell());
				if (i == grid.getRowCount() - 1)
					cell.addStyleName(style.bottomEdge());
				if (j == grid.getCellCount(i) - 1)
					cell.addStyleName(style.rightEdge());
				
				Label space = new Label();
				space.addStyleName(style.letter());
				cell.add(space);
				spaces.get(i).add(space);
				
				grid.setWidget(i, j, cell);
			}
		}
	}
	
	public String getWidth() {
		return grid.getColumnCount() * 26 + "px";
	}
	
	public String getHeight() {
		return grid.getRowCount() * 26 + "px";
	}
	
	@Override
	public void setCellAppearance(int x, int y, boolean left, boolean top, int number) {
		Panel cell = (Panel)grid.getWidget(y, x);
		if (left) cell.addStyleName(style.leftBar());
		if (top) cell.addStyleName(style.topBar());
		if (number > 0) {
			Label n = new Label("" + number);
			n.addStyleName(style.number());
			if (left) {
				n.addStyleName(style.leftBarNumber());
				spaces.get(y).get(x).addStyleName(style.leftBarLetter());
			}
			if (top) {
				n.addStyleName(style.topBarNumber());
				spaces.get(y).get(x).addStyleName(style.topBarLetter());
			}
			cell.add(n);
		}
	}
	
	@Override
	public void setCellSelected(int x, int y, boolean light, boolean selected) {
		Widget cell = grid.getWidget(y, x);
		
		if (light)
			cell.addStyleName(style.light());
		else
			cell.removeStyleName(style.light());

		if (selected)
			cell.addStyleName(style.selected());
		else
			cell.removeStyleName(style.selected());
	}

	@Override
	public int[] getClickedCell(ClickEvent event) {
		Cell target = grid.getCellForEvent(event);
		int[] loc = { target.getCellIndex(), target.getRowIndex() };
		return loc;
	}

	@Override
	public HandlerRegistration addClickHandler(ClickHandler handler) {
		return grid.addClickHandler(handler);
	}

	@Override
	public void setCellValue(int x, int y, char c) {
		spaces.get(y).get(x).setText(c + "");
	}
	
	@Override
	public void setLetters(String value) {
		int i = 0;
		for (List<Label> row : spaces)
			for (Label cell : row) {
				if (i >= value.length())
					break;
				cell.setText(value.substring(i, i+1));
				i++;
			}
	}

	@Override
	public String getLetters() {
		String res = "";
		for (List<Label> row : spaces)
			for (Label cell : row) {
				String s = cell.getText();
				if (s.equals(""))
					res += " ";
				else
					res += s;
			}
		return res;
	}
}